/*++

Copyright (c) 2007  Microsoft Corporation 

Filename: 

    ConfigureServerShape.cs

Abstract: 

    A class that configures each shape with respect to NRTM.
     
--*/

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using Visio = Microsoft.Office.Interop.Visio;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Data;
using System.Reflection;
using System.IO;
using System.Globalization;

namespace NRTMAddIn
{
    class ConfigureServerShape
    {
        internal const string NetworkNameProp = "Prop.NetworkName";
        internal const string IPAddressProp = "Prop.IPAddress";

        /// <summary>
        /// Default Constructor
        /// </summary>
        private ConfigureServerShape()
        {
         
        }    

        /// <summary>
        /// Visio drop shape event
        /// </summary>
        /// <param name="Shape"></param>
        internal static void VisioApp_ShapeAdded(Visio.Shape Shape)
        {
            try
            {
                
                //Shape must contain IP address and Network name
                if (!ValidNetworkShape(Shape))
                {
                    return;
                }

                //Configure server shape for NRTM usage

                //Add NRTMConfig property to the shape
                AddNRTMConfigProperties(Shape);

                //Add smart tag to shape
                LinkMonitorTagToShape(Shape);

                //Add NRTMStatus property to the shape
                AddStatusProperty(Shape);

                //Add the view details action menu
                AddViewDetailOption(Shape);

                //Set the tool tip to disk status
                Shape.get_CellsSRC(
                    (short)Visio.VisSectionIndices.visSectionObject,
                    (short)Visio.VisRowIndices.visRowMisc,
                    (short)Visio.VisCellIndices.visComment).Formula = "IF(PROP.NRTMCONFIG=TRUE,Prop.NetworkName & \" \" & IF(USER.NRTMSTATUS=0,\"Unavailable\",IF(USER.NRTMSTATUS=1,\"Low Disk\",IF(USER.NRTMSTATUS=2,\"Normal\",IF(USER.NRTMSTATUS=3,\"Healthy\",\"\")))),INDEX(0,INDEX(0,MASTERNAME(),\":\"),\".\"))";
            }
            catch (NrtmException ex)
            {
                //To catch and display exceptions from sub functions
                NrtmException.HandleExceptions(Global.GetResourceString("Exception_MsgBox_Caption"),
                            Global.GetResourceString("Exception_UsrMsg"), ex.InnerException);
            }
            catch (Exception ex)
            {
                //To catch exceptions from current functions
                NrtmException.HandleExceptions(Global.GetResourceString("Exception_MsgBox_Caption"),
                            Global.GetResourceString("Exception_UsrMsg"), ex);
            }
        }

        /// <summary>
        /// Add NRTMConfig property to the shape
        /// </summary>
        /// <param name="shape"></param>
        private static void AddNRTMConfigProperties(Visio.Shape shape)
        {
            // Add one named row, if they do not already exist.
            bool hasNRTM_ConfigProp;
            short rowIndex;
            Visio.Cell labelCell;

            try
            {
                hasNRTM_ConfigProp = ShapePropertyExist(shape, "Prop.NRTMConfig");

                if (!hasNRTM_ConfigProp)
                {
                    // Add a user-defined cell to store the NRTM Config name.
                    rowIndex = shape.AddNamedRow(
                        (short)(Visio.VisSectionIndices.visSectionUser),
                        "NRTMConfig",
                        (short)(Visio.VisRowIndices.visRowUser));

                    // Get the Value cell and set it to point 
                    // to a value from the NodeInfo property cell.
                    shape.get_Cells("User.NRTMConfig.Value").FormulaU = "TRUE";

                    // Insert our NRTMConfig property.
                    rowIndex = shape.AddNamedRow(
                        (short)(Visio.VisSectionIndices.visSectionProp),
                        "NRTMConfig",
                        (short)(Visio.VisRowIndices.visRowProp));

                    // Edit the Label cell.
                    labelCell = shape.get_CellsSRC(
                        (short)Visio.VisSectionIndices.visSectionProp,
                        rowIndex,
                        (short)Visio.VisCellIndices.visCustPropsLabel);
                    labelCell.FormulaU = "\"NRTM Configured\"";

                    // True if user cell is true & ip address or network name is specified
                    shape.get_Cells("Prop.NRTMConfig.Value").Formula = "AND(TheDoc!User.NRTMAvail=TRUE,AND(USER.NRTMCONFIG=TRUE,OR(AND(LOCALFORMULAEXISTS(Prop.NetworkName),NOT(STRSAME(Prop.NetworkName,\"\"))),AND(LOCALFORMULAEXISTS(Prop.IPAddress),NOT(STRSAME(Prop.IPAddress,\"\"))))))";

                    //Set Invisible to true.
                    shape.get_Cells("Prop.NRTMConfig.Invisible").FormulaU = "TRUE";
                }
            }
            catch (Exception ex)
            {
                //Throw user-defined exception
                throw new NrtmException("Add NRTM Config Property", ex);
            }
        }

        /// <summary>
        /// Add smart tag to shape
        /// </summary>
        /// <param name="shape"></param>
        private static void LinkMonitorTagToShape(Visio.Shape shape)
        {
            bool hasNRTM_ConfigProp;

            try
            {
                hasNRTM_ConfigProp = ShapePropertyExist(shape, "Prop.NRTMConfig");
                if (hasNRTM_ConfigProp)
                {
                    string NRTMConfig = shape.get_Cells("User.NRTMConfig.Value").FormulaU;
                    //NRTMConfig should be true for a shape to add the smart tag
                    if (NRTMConfig == "TRUE")
                    {
                        bool hasTag = ShapePropertyExist(shape, "SmartTags.NRTMTag");
                        if (!hasTag)
                        {
                            short SmartSection = (short)(Visio.VisSectionIndices.visSectionSmartTag);
                            shape.AddNamedRow(SmartSection, "NRTMTag", (short)Visio.VisRowIndices.visRowSmartTag);
                            shape.get_CellsU("SmartTags.NRTMTag.TagName").FormulaU = "\"Disk Monitor\"";
                            //Enable only if shape is NRTM configured
                            shape.get_CellsU("SmartTags.NRTMTag.Disabled").Formula = "NOT(Prop.NRTMConfig)";

                            //Set menu action
                            short SmartTagAction = (short)(Visio.VisSectionIndices.visSectionAction);
                            shape.AddNamedRow(SmartTagAction, "NRTMTag", (short)Visio.VisRowIndices.visRowAction);
                            shape.get_CellsU("Actions.NRTMTag.TagName").FormulaU = "\"Disk Monitor\"";
                            shape.get_CellsU("Actions.NRTMTag.Menu").FormulaU = "\"" + Global.GetResourceString("Start_SmartTag") + "\"";
                            shape.get_CellsU("Actions.NRTMTag.Action").FormulaU = "RUNADDONWARGS(\"QUEUEMARKEREVENT\",\"" +
                                            Global.ApplicationContextString + Global.ApplicationIndex +
                                            " " + Global.CommandContextString + Global.CommandStringStartMonitoring + "\")";
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //Throw user-defined exception
                throw new NrtmException("Add NRTM Smart Tag", ex);
            }
        }

        /// <summary>
        /// Add NRTMStatus property to the shape
        /// </summary>
        /// <param name="shape"></param>
        private static void AddStatusProperty(Visio.Shape shape)
        {
            // Add one named row, if they do not already exist.
            bool hasNRTMStatusProp;
            try
            {
                hasNRTMStatusProp = ShapePropertyExist(shape, "User.NRTMStatus");
                if (!hasNRTMStatusProp)
                {

                    // Add a user-defined cell to store the NRTM Status name.
                    shape.AddNamedRow(
                        (short)(Visio.VisSectionIndices.visSectionUser),
                        "NRTMStatus",
                        (short)(Visio.VisRowIndices.visRowUser));
                }
                //Set to default
                shape.get_CellsU("User.NRTMStatus").set_ResultFromInt(
                            (short)Visio.VisUnitCodes.visNoCast,
                             Convert.ToInt32(Global.VisioColors.Default, CultureInfo.InvariantCulture));
            }
            catch (Exception ex)
            {
                //Throw user-defined exception
                throw new NrtmException("Add NRTM status Property", ex);
            }
        }

        /// <summary>
        /// Add the view details action menu
        /// </summary>
        /// <param name="shape"></param>
        private static void AddViewDetailOption(Visio.Shape shape)
        {
            //Check if view details already exisit
            bool hasViewDetailAction = ShapePropertyExist(shape, "Actions.DrillAction");
            try
            {
                if (!hasViewDetailAction)
                {
                    short ActionSection = (short)(Visio.VisSectionIndices.visSectionAction);
                    shape.AddNamedRow(ActionSection, "DrillAction", (short)Visio.VisRowIndices.visRowAction);
                    shape.get_CellsU("Actions.DrillAction.Action").FormulaU = "RUNADDONWARGS(\"QUEUEMARKEREVENT\",\"" +
                        Global.ApplicationContextString + Global.ApplicationIndex +
                        " " + Global.CommandContextString + Global.CommandStringDrill + "\")";
                    shape.get_CellsU("Actions.DrillAction.Menu").FormulaU = "\""+Global.GetResourceString("ViewDiskDetails_Text")+"\"";
                    //Active only if shape is NRTM configured & status is between 0-3
                    shape.get_CellsU("Actions.DrillAction.Invisible").Formula = "NOT(AND(TheDoc!User.NRTMMonitor,AND(PROP.NRTMCONFIG,OR(OR(USER.NRTMSTATUS=0,USER.NRTMSTATUS=1),OR(USER.NRTMSTATUS=2,USER.NRTMSTATUS=3)))))";
                }
            }
            catch (Exception ex)
            {
                //Throw user-defined exception
                throw new NrtmException("Add NRTM details property", ex);
            }
        }

        /// <summary>
        /// Check if the shape contains the property
        /// </summary>
        /// <param name="shape">Visio Shape</param>
        /// <param name="propertyName">Property Name</param>
        /// <returns>True if shape contains the property</returns>
        internal static bool ShapePropertyExist(Visio.Shape shape,string propertyName)
        {
            return Convert.ToBoolean(shape.get_CellExists(propertyName, (short)Visio.VisExistsFlags.visExistsAnywhere));
        }

        /// <summary>
        /// Checks if a shape contains IP address and Network name properties
        /// </summary>
        /// <param name="shape">Shape to validate</param>
        /// <returns>True if IP address and Network name present</returns>
        internal static bool ValidNetworkShape(Visio.Shape shape)
        {
            if (ShapePropertyExist(shape, NetworkNameProp) && ShapePropertyExist(shape, IPAddressProp))
            {
                //Return true if shape contains IP address & Network name
                return true;
            }
            return false;
        }
    }
}
